package utils

import (
	"encoding/base64"
	"math/rand"
)

func EncryptBuf(srcBuf, keyBuf []byte) []byte {
	offset := byte(rand.Intn(255))
	var rb BytesBuilder
	rb.WriteByte(byte(offset))
	keyPos := 0
	for srcPos := 0; srcPos < len(srcBuf); srcPos++ {
		v1 := int(srcBuf[srcPos]) + int(offset)
		SrcAsc := byte(v1 % 255)
		SrcAsc = SrcAsc ^ keyBuf[keyPos]
		keyPos++
		if keyPos >= len(keyBuf) {
			keyPos = 0
		}
		rb.WriteByte(SrcAsc)
		offset = SrcAsc
	}
	return rb.Bytes()
}

func DecryptBuf(encryptBuf, keyBuf []byte) []byte {
	srcBuf := encryptBuf
	if len(srcBuf) == 0 {
		return nil
	}

	keyPos := 0
	offset := srcBuf[0]
	var rb BytesBuilder
	for i := 1; i < len(srcBuf); i++ {
		SrcAsc := srcBuf[i]
		TmpSrcAsc := SrcAsc ^ keyBuf[keyPos]
		if TmpSrcAsc <= offset {
			TmpSrcAsc = 255 + TmpSrcAsc - offset
		} else {
			TmpSrcAsc = TmpSrcAsc - offset
		}
		rb.WriteByte(TmpSrcAsc)
		keyPos++
		if keyPos >= len(keyBuf) {
			keyPos = 0
		}
		offset = SrcAsc
	}

	return rb.Bytes()
}

func Encrypt(src, key string) string {
	buf := EncryptBuf([]byte(src), []byte(key))
	return BufToHexStr(buf, 0, "")
}

func Decrypt(encryptstr, key string) string {
	srcBuf := HexStrToBuf(encryptstr)
	buf := DecryptBuf(srcBuf, []byte(key))
	return string(buf)
}

/*
**

	对字符串进行加密/解密
*/
func EncryptBase64(src, key string) string {
	buf := EncryptBuf([]byte(src), []byte(key))
	return base64.RawURLEncoding.EncodeToString(buf)
}

/*
**

	对字符串进行加密/解密
*/
func EncryptHexString(src, key string) string {
	buf := EncryptBuf([]byte(src), []byte(key))
	return BufToHexStr(buf, 0, "")
}

func DecryptBase64V0(encrypt, key string) (string, error) {
	src, err := base64.RawURLEncoding.DecodeString(encrypt)
	if err != nil {
		return "", err
	}

	if len(src) == 0 {
		return "", nil
	}

	buf := DecryptBuf(src, []byte(key))
	return string(buf), nil
}

func DecryptBase64(encrypt, key string) string {
	src, err := base64.RawURLEncoding.DecodeString(encrypt)
	if err != nil {
		return ""
	}

	if len(src) == 0 {
		return ""
	}

	buf := DecryptBuf(src, []byte(key))
	return string(buf)
}

func DecryptHexString(encrypt, key string) string {
	src := HexStrToBuf(encrypt)
	if len(src) == 0 {
		return ""
	}

	buf := DecryptBuf(src, []byte(key))
	return string(buf)
}
